home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / stufit2.zip / STUFIT2.ASM < prev    next >
Assembly Source File  |  1989-07-26  |  29KB  |  1,038 lines

  1. ;==========================================================================
  2. ;==                                         ==
  3. ;==                    STUFIT                         ==
  4. ;==========================================================================
  5.  
  6. ;Utility to move designated files to the inner tracks of a disk.
  7. ;
  8. ;Disassembled and heavily hacked, with most of the significant changes
  9. ;annotated with the "v1.x" comments.
  10. ;
  11. ;Incorporating DOS v3.x/4.x patches from:
  12. ;    Hylton Boothroyd, University of Warwick, 890710
  13. ;See his notes at the end.
  14. ;
  15. ; - No need to reset DTA for each file.
  16. ;   Just doing it once now (at Find_First)
  17. ;
  18. ; - Confirmed via tests, no need to "force DOS next free space"
  19. ;   at every run (as in Hylton's original patch).
  20. ;   Just doing it once now (at Check_DOS_Version)
  21. ;
  22. ;I've noticed the program halts when it hits a file too big to relocate
  23. ;(e.g., free space is less than target file size).
  24. ;This is as it should be .. but halting right there is not so very smart:
  25. ;we should be smart enough to go on beyond that too-big file in case
  26. ;there are smaller ones that WILL fit.
  27. ;
  28. ;In the meantime, this utility will work best if you use a directory sorting
  29. ;utility (like Norton's Utilities) to sort in order of file size
  30. ;(smallest files first).
  31. ;
  32. ;This enables the "Find First" and "Find Next" functions to pick up
  33. ;files in an order most likely to maximize the number of files that can
  34. ;be moved to the innermost tracks.  (Assuming you have a free space
  35. ;limitation that prohibits moving ALL files.)
  36. ;
  37. ;
  38. ;We're also sticking with the sheer brute-force method of forcing
  39. ;our "next free space" to disk end (via creating a temporary free-space
  40. ;holding file that gobbles ALL the free space on the disk .. except for
  41. ;the space required for the target file copy).
  42. ;
  43. ;There oughtta be a way to fool DOS into finding free space working
  44. ;backwards from the inside tracks, or from the last new file we created
  45. ;during relocation.  Unfortunately, I can't think of any way!
  46. ;
  47. ;
  48. ;David Kirschbaum
  49. ;Toad Hall
  50. ;kirsch@braggvax.ARPA
  51.  
  52. CR    equ    0DH
  53. LF    equ    0AH
  54.  
  55. CSEG    SEGMENT PUBLIC PARA 'CODE'
  56.     ASSUME    CS:CSEG, DS:CSEG, ES:CSEG
  57.  
  58.         org    0
  59. cseg_org    label    byte            ;needed to help MASM
  60.                         ;figure buffer size    v1.1
  61.  
  62.         org    80H
  63. cmdline        label    byte            ;v1.1
  64.  
  65.         org    100h
  66.  
  67. StufIt        proc    near
  68.  
  69.         jmp    Start
  70.  
  71. ;v1.2    Some data previously scattered around the program
  72. ;    consolidated here.
  73.  
  74. ourDTA    label    byte                    ;working dta
  75.     db    'dta2dta2dta2dta2dta2dta2dta2dt'
  76. ;DTA+30                            ;file name psn
  77.                             ;within DTA
  78.     db    'a2'
  79.     db    'dta2dta2dta2dta2dta2dta2dta2dta2'
  80.     db    'dta2dta2dta2dta2dta2dta2dta2dta2'
  81.     db    'dta2dta2dta2dta2dta2dta2dta2dta2'
  82.  
  83. targetname    label    byte                ;quite a buffer!
  84.     db    'filenamefilenamefilenamefilename'
  85.     db    'filenamefilenamefilenamefilename'
  86.     db    'filenamefilenamefilenamefilename'
  87.     db    'filenamefilenamefilenamefilename'
  88.  
  89. ;for current filename display
  90. namelen    dw    0                    ;length
  91. nameptr    dw    targetname                ;ptr to filename
  92.  
  93.  
  94. StufIt        endp
  95.  
  96. ;==========================================================================
  97. ;                   SUBROUTINE
  98. ;==========================================================================
  99.  
  100.  
  101. err2    db    '-File not found-',CR,LF,'$'
  102. err3    db    '-Path not found-',CR,LF,'$'
  103. err4    db    '-Too many open files (no handles left)-',CR,LF,'$'
  104. err5    db    '-Access denied-',CR,LF,'$'
  105. err6    db    '-Invalid handle-',CR,LF,'$'
  106. err0C    db    '-Invalid access code-',CR,LF,'$'
  107. err11    db    '-Not same device-',CR,LF,'$'
  108. err12    db    '-No more files-',CR,LF,'$'
  109. err1C    db    '-Write error-',CR,LF,'$'        ;v1.1
  110. errunk    db    '-Unrecognized error code-'
  111. crlf$    db    CR,LF,'$'            ;share this    v1.1
  112.  
  113. ;Vastly tightened
  114. ;Enter with:
  115. ;  AX = file error
  116. ;  DX = first error message
  117.  
  118. Rpt_Error    proc    near            ;v1.1
  119.  
  120.     mov    bx,ax            ;save error value        v1.1
  121.     mov    si,dx            ;and msg ptr            v1.1
  122.     mov    dx,offset crlf$        ;always a new line        v1.1
  123.     mov    ah,9            ;display msg            v1.1
  124.     int    21H            ;                v1.1
  125.     mov    dx,si            ;first msg ptr            v1.1
  126.     mov    ah,9            ;display msg            v1.1
  127.     int    21H            ;                v1.1
  128.     mov    ax,bx            ;restore error            v1.1
  129.  
  130.     mov    dx,offset err2        ;'file not found'
  131.     cmp    al,2
  132.     jz    Pr_ErrMsg
  133.  
  134.     mov    dx,offset err3        ;'Path not found'
  135.     cmp    al,3
  136.     jz    Pr_ErrMsg
  137.  
  138.     mov    dx,offset err4        ;'Too many open files'
  139.     cmp    al,4
  140.     jz    Pr_ErrMsg
  141.  
  142.     mov    dx,offset err5        ;'Access denied'
  143.     cmp    al,5
  144.     jz    Pr_ErrMsg
  145.  
  146.     mov    dx,offset err6        ;'Invalid handle'
  147.     cmp    al,6
  148.     jz    Pr_ErrMsg
  149.  
  150.     mov    dx,offset err0C        ;'Invalid access code'
  151.     cmp    al,0CH
  152.     jz    Pr_ErrMsg
  153.  
  154.     mov    dx,offset err11        ;'Not same device'
  155.     cmp    al,11H
  156.     jz    Pr_ErrMsg
  157.  
  158.     mov    dx,offset err12        ;'No more files'
  159.     cmp    al,12H
  160.     jz    Pr_ErrMsg
  161.  
  162.     mov    dx,offset err1C        ;'Write error'            v1.1
  163.     cmp    al,1CH            ;                v1.1
  164.     jz    Pr_ErrMsg        ;                v1.1
  165.  
  166.     mov    dx,offset errunk    ;'Unknown error'
  167.  
  168. Pr_ErrMsg:
  169.     mov    bx,ax            ;save error value        v1.1
  170.     mov    ah,9            ;display msg
  171.     int    21H
  172.     mov    ax,bx            ;restore error value        v1.1
  173.     stc                ;always return CF set        v1.1
  174.     ret
  175.  
  176. Rpt_Error    endp
  177.  
  178. ;==========================================================================
  179. ;                   SUBROUTINE
  180. ;==========================================================================
  181.  
  182. ;Wonder why he bothered with these default values?
  183.  
  184. bytesPerSector        dw    0        ;was 200h        v1.2
  185. sectorsPerCluster    dw    0        ;was 8            v1.2
  186. bytesPerCluster        dw    0        ;was 1000h        v1.2
  187.  
  188. nrClusters        dw    0        ;was 0A1AH        v1.2
  189. avail$            db    'avail: $'    ;            v1.1
  190. availClusters        dw    0
  191.  
  192.  
  193. Get_FreeSpace    proc    near
  194.  
  195.     mov    ah,36h            ;get free space
  196.     xor    dx,dx            ;current drive            v1.1
  197.     int    21h
  198.     jnc    Loc_12            ;got it ok
  199.  
  200.     mov    dx,offset avail$    ;'avail: '
  201.     jmp    Rpt_Error        ;display error msg,        v1.1
  202.                     ;return from there CF set
  203.  
  204. Loc_12:
  205.     mov    availClusters,bx    ;available cluster count
  206.     mov    nrClusters,dx        ;total clusters
  207.     mov    bytesPerSector,cx    ;bytes per sector
  208.     mov    sectorsPerCluster,ax    ;sectors per cluster
  209.     mul    cx
  210.     mov    bytesPerCluster,ax    ;bytes per cluster
  211.     clc                ;return CF clear
  212.     ret
  213.  
  214. Get_FreeSpace        endp
  215.  
  216.  
  217. ;==========================================================================
  218. ;                   SUBROUTINE
  219. ;==========================================================================
  220.  
  221. getfirst$    db    'getfirst: $'        ;v1.1
  222. getnext$    db    'getnext: $'        ;v1.1
  223.  
  224. ;Code for Find First and Find Next
  225.  
  226. Find_File    proc    near
  227.  
  228. Find_Next:
  229.  
  230. ;v1.2    I wonder why we keep resetting the DTA?
  231. ;    We did it once at Find_First .. why again and again?
  232. ;    Trying this without the DTA reset
  233.  
  234. Comment    ~
  235.     mov    dx,offset ourDTA    ;working DTA
  236.     mov    ah,1AH            ;set DTA to DS:DX
  237.     int    21h
  238.     jc    FindNext_Fail        ;failed
  239. Comment    ends    ~
  240.  
  241.     mov    ah,4FH            ;find next filename
  242.     int    21h
  243.  
  244. ;v1.1    jc    FindNext_Fail        ;failed
  245. ;Wrongo!  Find Next does NOT use the CF to indicate success/failure.
  246. ;Instead, AX returns a value (0 if found).
  247.  
  248.     or    ax,ax            ;found it?
  249.     jnz    FindNext_Fail        ;nope, die
  250.  
  251.      mov    si,nameptr        ;get ptr to filename
  252.      jmp    short Find_Common    ; and continue
  253.  
  254.  
  255. FindNext_Fail:
  256.     mov    dx,offset getnext$    ;'getnext: '
  257.     jmp    Rpt_Error        ;display file error        v1.1
  258.                     ;return from there CF set
  259.  
  260. ;Enter here for the Find First.
  261.  
  262. Find_First:
  263.     mov    dx,offset ourDTA    ;working DTA
  264.     mov    ah,1AH            ;set DTA to DS:DX
  265.     int    21h
  266.     jc    FindFirst_Fail        ;failed                v1.1
  267.  
  268.     mov    dx,offset targetname    ;filename buffer
  269.     xor    cx,cx            ;no special attribs
  270.     mov    ah,4Eh            ;find first
  271.     int    21h
  272.  
  273. ;v1.1    jnc    Loc_19            ;found it
  274. ;Wrongo!  Find First doesn't use the carry flag to indicate
  275. ;success or failure!  Results are in AX!
  276.  
  277.     or    ax,ax            ;0 means success        v1.1
  278.     jnz    FindFirst_Fail        ;didn't find it            v1.1
  279.     
  280.     mov    si,offset targetname-1    ;filename buffer-1
  281.     mov    cx,namelen        ;name length            v1.1
  282.     add    si,cx            ;bump filename ptr also        v1.1
  283.     std                ;move backwards
  284.  
  285. LocLoop_20:
  286.     lodsb                ;snarf target filename char
  287.     cmp    al,'\'            ;part of a path?
  288.     je    NameStart_21        ;yep
  289.     cmp    al,'/'            ;could be using this as path
  290.     je    NameStart_21        ;yep
  291.     cmp    al,':'            ;how about a drive separator?
  292.     je    NameStart_21        ;yep
  293.     loop    LocLoop_20        ;just a name char
  294.  
  295.     dec    si            ;adjust from last lodsb
  296.  
  297. NameStart_21:
  298.     mov    nameptr,si        ;save ptr to filename start
  299.  
  300. ;Common code for Find_First and Find_Next
  301.  
  302. Find_Common:
  303.     mov    di,si            ;target filename start
  304.     mov    si,offset ourDTA+30    ;30 bytes into workin